use crate::dao::DataItemDao;
use crate::models::{DataItem, DataItemsReturn};
use r2d2::Pool;
use r2d2_sqlite::SqliteConnectionManager;
use serde_json::value::Value;

pub struct DataItemService {
    data_item_dao: DataItemDao,
}

impl DataItemService {
    pub fn new(pool: Pool<SqliteConnectionManager>) -> Self {
        let data_item_dao = DataItemDao::new(pool);
        DataItemService { data_item_dao }
    }

    pub fn init_table(&self) -> Result<(), rusqlite::Error> {
        self.data_item_dao.create_table()
    }

    pub fn insert_data_item(&self, data_item: &DataItem) -> Result<(), rusqlite::Error> {
        self.data_item_dao
            .insert(data_item)
            .expect("Failed to insert data item");
        Ok(())
    }

    pub async fn get_all_data_items(&self) -> Result<Vec<DataItem>, rusqlite::Error> {
        self.data_item_dao.get_all_data_items()
    }

    pub fn get_data_items_by_time_range(
        &self,
        after: &str,
        before: &str,
        name: &str,
    ) -> Result<Vec<Value>, rusqlite::Error> {
        self.data_item_dao
            .get_data_items_by_time_range(after, before, name)
    }

    pub fn get_data_data_items_by_time_range_and_page(
        &self,
        after: &str,
        before: &str,
        page: i32,
        name: &str,
    ) -> Result<DataItemsReturn, rusqlite::Error> {
        let count = self
            .data_item_dao
            .get_count_by_time_range(after, before, name);
        let data_items = self
            .data_item_dao
            .get_data_data_items_by_time_range_and_page(after, before, page, 20, name);
        Ok(DataItemsReturn {
            data: data_items?,
            total: count?,
        })
    }
}
